﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MS.InformationManagement.DAL.DocumentCenter;
using Microsoft.SharePoint;
using MS.InformationManagement.Core.Support;
using MS.InformationManagement.Support.Constants;
using MS.InformationManagement.Core.RecordSiteQuery;
using MS.InformationManagement.DAL.RecordCenter;
using MS.InformationManagement.DAL.Support;
using System.Data;
using Microsoft.SharePoint.Taxonomy;
using MS.InformationManagement.Support;

namespace MS.InformationManagement.BLL.ExpedienteViewer
{
    public class ExpedienteViewer
    {

        public IEnumerable<Radicado> GetRadicadosByExpediente(string expedienteId, int? pageIndex, int? pageSize, out int totalRecords)
        {
            ////Este era el metodo anterior molestaba en la parte de expedienteInfo.Rows[0][3].ToString(); pues el SPSiteDataQuery solo retornaba dos campos.
            ////En vm-minhacienda al pasar SPContext.Current.Web.Lists[listName]; tomaba el list name como string y no como guid y nunca encontraba la lista
            ////Se convirtio primero el id de la lista a guid para encontrar la lista

            //var expedienteInfo = getExpedienteInformation(expedienteId);
            //if (expedienteInfo == null || expedienteInfo.Rows.Count == 0)
            //    throw new Exception("Expediente no encontrado");
            //string listName = expedienteInfo.Rows[0][3].ToString();
            //string listItemId = expedienteInfo.Rows[0]["ID"].ToString();
            //SPFolder currentFolder = SPContext.Current.Web.Lists[listName].GetItemById(int.Parse(listItemId)).Folder;
            //IEnumerable<Radicado> radicadosExpediente = getRadicadosExpediente(currentFolder);
            //return radicadosExpediente;

            int startingPosition = pageIndex == null ? 1 : (int)pageIndex * (int)pageSize;
            var expedienteInfo = getExpedienteInformation(expedienteId);
            if (expedienteInfo == null || expedienteInfo.Rows.Count == 0)
                throw new Exception("Expediente no encontrado");
            Guid listName = new Guid(expedienteInfo.Rows[0][0].ToString());
            string listItemId = expedienteInfo.Rows[0]["ID"].ToString();
            SPList currentRadicadoList = SPContext.Current.Web.Lists[listName];
            SPFolder currentFolder = currentRadicadoList.GetItemById(int.Parse(listItemId)).Folder;
            IEnumerable<Radicado> radicadosExpediente = getRadicadosExpediente(currentFolder);
            totalRecords = radicadosExpediente.Count();
            if (pageIndex == null) return radicadosExpediente;
            else return radicadosExpediente.Skip(startingPosition).Take((int)pageSize);
        }

        public void UpdateExpediente(Expediente expediente)
        {
            //using (var dc = new DCDocumentCenterDataContext(SPContext.Current.Web.Url))
            //{
            //    var entity = (from exp in dc.GetList<Expediente>(PeopleHelper.GetPropertyCurrentUserProfile(GlobalConstants.UP_DEPARTMENT))//UserLibraryHelper.CurrentUserLibraryName)
            //                  where exp.NúmeroExpediente == expediente.NúmeroExpediente
            //                  select exp).FirstOrDefault();
            //    entity.Asunto = expediente.Asunto;
            //    dc.SubmitChanges();
            //}

            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (SPSite site = new SPSite(SPContext.Current.Web.Url))
                {
                    using (SPWeb miWeb = site.OpenWeb())
                    {
                        var expedienteInfo = getExpedienteInformation(expediente.NúmeroExpediente);
                        if (expedienteInfo == null || expedienteInfo.Rows.Count == 0)
                            throw new Exception("Expediente no encontrado");
                        Guid listName = new Guid(expedienteInfo.Rows[0][0].ToString());
                        string listItemId = expedienteInfo.Rows[0]["ID"].ToString();
                        SPList currentRadicadoList = SPContext.Current.Web.Lists[listName];

                        miWeb.AllowUnsafeUpdates = true;
                        SPListItem currentItem = currentRadicadoList.GetItemById(int.Parse(listItemId));
                        currentItem[CustomSiteColumns.FIELD_EXPEDIENTE_SUBJECT] = expediente.Asunto;
                        currentItem.Update();

                        miWeb.AllowUnsafeUpdates = false;
                    }
                }
            });
        }

        public Expediente GetExpediente(string expedienteId)
        {
            List<string> viewFields = new List<string>() { 
                                                           CustomSiteColumns.FIELD_DOCUMENT_EXPEDIENTE_ID, 
                                                           CustomSiteColumns.FIELD_EXPEDIENTE_CODIGO,
                                                           CustomSiteColumns.FIELD_EXPEDIENTE_START,
                                                           CustomSiteColumns.FIELD_EXPEDIENTE_END,
                                                           CustomSiteColumns.FIELD_EXPEDIENTE_SUBJECT,
                                                           CustomSiteColumns.FIELD_EXPEDIENTE_LOCATION,
                                                           CustomSiteColumns.FIELD_EXPEDIENTE_LOCATION_KIND,
                                                           CustomSiteColumns.FIELD_EXPEDIENTE_NOTES,
                                                           CustomSiteColumns.FIELD_EXPEDIENTE_SUBSERIE,
                                                           CustomSiteColumns.FIELD_EXPEDIENTE_ASSIGNED
                                                         };
            List<string> viewListFields = new List<string>() { "Title" };
            string camlQuery = string.Format("<Where><And><Eq><FieldRef Name='{0}' /><Value Type='Text'>{1}</Value></Eq><Eq><FieldRef Name='{2}' /><Value Type='Text'>{3}</Value></Eq></And></Where>", CustomSiteColumns.FIELD_DOCUMENT_EXPEDIENTE_ID, expedienteId, UserLibraryHelper.ContentTypeFieldName, GlobalConstants.CTTN_EXPEDIENTE);
            SPSiteDataQuery query = QuerySiteHelper.getSiteQueryObject(GlobalConstants.GLOBAL_USER_LIBRARY_TEMPLATE, viewFields, viewListFields, camlQuery);
            DataTable foundedItems = SPContext.Current.Web.GetSiteData(query);
            Expediente exp = new Expediente();
            exp.NúmeroExpediente = foundedItems.Rows[0][CustomSiteColumns.FIELD_DOCUMENT_EXPEDIENTE_ID] == null ? string.Empty : foundedItems.Rows[0][CustomSiteColumns.FIELD_DOCUMENT_EXPEDIENTE_ID].ToString();
            exp.Código = foundedItems.Rows[0][CustomSiteColumns.FIELD_EXPEDIENTE_CODIGO] == null ? string.Empty : foundedItems.Rows[0][CustomSiteColumns.FIELD_EXPEDIENTE_CODIGO].ToString();
            exp.Asunto = foundedItems.Rows[0][CustomSiteColumns.FIELD_EXPEDIENTE_SUBJECT] == null ? string.Empty : foundedItems.Rows[0][CustomSiteColumns.FIELD_EXPEDIENTE_SUBJECT].ToString();
            exp.UbicaciónFisica = foundedItems.Rows[0][CustomSiteColumns.FIELD_EXPEDIENTE_LOCATION] == null ? string.Empty : foundedItems.Rows[0][CustomSiteColumns.FIELD_EXPEDIENTE_LOCATION].ToString();
            exp.TipoUbicación = foundedItems.Rows[0][CustomSiteColumns.FIELD_EXPEDIENTE_LOCATION_KIND] == null ? TipoUbicación.Invalid : (TipoUbicación)Enum.Parse(typeof(TipoUbicación), foundedItems.Rows[0][CustomSiteColumns.FIELD_EXPEDIENTE_LOCATION_KIND].ToString());
            exp.Notas = foundedItems.Rows[0][CustomSiteColumns.FIELD_EXPEDIENTE_NOTES] == null ? string.Empty : foundedItems.Rows[0][CustomSiteColumns.FIELD_EXPEDIENTE_NOTES].ToString();
            exp.SubserieName = foundedItems.Rows[0][CustomSiteColumns.FIELD_EXPEDIENTE_SUBSERIE] == null ? string.Empty : QueryRecordsSiteHelper<Subserie>.QueryRecordsEntityById(GlobalConstants.LIST_BIBLIOTECA_SUBSERIE, int.Parse(foundedItems.Rows[0][CustomSiteColumns.FIELD_EXPEDIENTE_SUBSERIE].ToString().Split('.')[0])).Title;
            exp.SerieName = foundedItems.Rows[0][CustomSiteColumns.FIELD_EXPEDIENTE_SUBSERIE] == null ? string.Empty : QueryRecordsSiteHelper<Subserie>.QueryRecordsEntityById(GlobalConstants.LIST_BIBLIOTECA_SUBSERIE, int.Parse(foundedItems.Rows[0][CustomSiteColumns.FIELD_EXPEDIENTE_SUBSERIE].ToString().Split('.')[0])).Serie.Title;
            exp.FechaInicial = foundedItems.Rows[0][CustomSiteColumns.FIELD_EXPEDIENTE_START] == null ? new Nullable<DateTime>() : DateTime.Parse(foundedItems.Rows[0][CustomSiteColumns.FIELD_EXPEDIENTE_START].ToString());
            exp.FechaFinal = foundedItems.Rows[0][CustomSiteColumns.FIELD_EXPEDIENTE_END] == null ? new Nullable<DateTime>() : DateTime.Parse(foundedItems.Rows[0][CustomSiteColumns.FIELD_EXPEDIENTE_END].ToString());
            exp.UsuarioAsignado = foundedItems.Rows[0][CustomSiteColumns.FIELD_EXPEDIENTE_ASSIGNED] == null ? string.Empty : foundedItems.Rows[0][CustomSiteColumns.FIELD_EXPEDIENTE_ASSIGNED].ToString();
            return exp;
        }

        public List<string> GetTipoUbicacion()
        {
            var choices = ((SPFieldChoice)SPContext.Current.Web.Fields[new Guid("{60EBDA6A-1B3C-4280-AD22-F73C41B2161F}")]).Choices;
            List<string> ubicaciones = new List<string>();
            foreach (var ubicacion in choices)
                ubicaciones.Add(ubicacion);
            return ubicaciones;
        }

        public void Incluir(string expedienteId, string radicadoId)
        {

            //List<string> viewFields = new List<string>() { "ID" };
            //List<string> viewListFields = new List<string>() { "Title" };
            //string camlQuery = string.Format("<Where><And><Eq><FieldRef Name='{0}' /><Value Type='Text'>{1}</Value></Eq><Eq><FieldRef Name='{2}' /><Value Type='Text'>{3}</Value></Eq></And></Where>", CustomSiteColumns.FIELD_DOCUMENT_EXPEDIENTE_ID, expedienteId, UserLibraryHelper.ContentTypeFieldName, GlobalConstants.CTTN_EXPEDIENTE);
            //SPSiteDataQuery query = QuerySiteHelper.getSiteQueryObject(GlobalConstants.GLOBAL_USER_LIBRARY_TEMPLATE, viewFields, viewListFields, camlQuery);

            //var expedienteInfo = SPContext.Current.Web.GetSiteData(query);
            var expedienteInfo = getExpedienteInformation(expedienteId);
            if (expedienteInfo == null || expedienteInfo.Rows.Count == 0)
                throw new Exception("Expediente no encontrado");
            string listName = expedienteInfo.Rows[0][3].ToString();
            string listItemId = expedienteInfo.Rows[0]["ID"].ToString();
            SPList currentList = SPContext.Current.Web.Lists.TryGetList(listName);
            SPFolder currentFolder = currentList.GetItemById(int.Parse(listItemId)).Folder;

            SPQuery query1 = new SPQuery();
            query1.Folder = currentFolder;
            query1.Query = "<Where><Eq><FieldRef Name='Document_Radicado' /><Value Type='Text'>" + radicadoId + "</Value></Eq></Where>";
            SPListItemCollection items = currentFolder.Item.ParentList.GetItems(query1);
            SPListItem targetRad = items[0];
            SPContext.Current.Web.AllowUnsafeUpdates = true;
            targetRad[MS.InformationManagement.Support.Constants.CustomSiteColumns.FIELD_DOCUMENT_FILED] = true;
            targetRad.Update();
            SPContext.Current.Web.AllowUnsafeUpdates = false;
        }

        public IEnumerable<Radicado> GetRadicadosByExpedienteAndVolume(string expedienteId, string volumeId, int pageIndex, int pageSize, out int totalRecords)
        {
            int startingPosition = pageIndex * pageSize;
            var expedienteInfo = getExpedienteInformation(expedienteId);
            if (expedienteInfo == null || expedienteInfo.Rows.Count == 0)
                throw new Exception("Expediente no encontrado");
            Guid listName = new Guid(expedienteInfo.Rows[0][0].ToString());
            string listItemId = expedienteInfo.Rows[0]["ID"].ToString();
            SPList currentRadicadoList = SPContext.Current.Web.Lists[listName];
            SPFolder currentFolder = currentRadicadoList.GetItemById(int.Parse(listItemId)).Folder;
            IEnumerable<Radicado> radicadosExpediente = getRadicadosExpediente(currentFolder);
            var radicadosTomo = from Radicado item in radicadosExpediente
                                where item.NúmeroTomo == volumeId
                                select item;
            totalRecords = radicadosTomo.Count();
            return radicadosTomo.Skip(startingPosition).Take(pageSize);
        }

        public DataTable GetRadicadosByExpedienteAndVolumeTable(string expedienteId, string volumeId)
        {
            if (expedienteId == string.Empty || volumeId == string.Empty)
                throw new Exception("El expediente o el tomo no existen");

            var expedienteInfo = getExpedienteInformation(expedienteId);
            if (expedienteInfo == null || expedienteInfo.Rows.Count == 0)
                throw new Exception("Expediente no encontrado");

            DataTable exportData = new DataTable();
            exportData.Columns.Add("Radicado");
            exportData.Columns.Add("Fecha Creacion");
            exportData.Columns.Add("Remitente / Destinatario");
            exportData.Columns.Add("Tipo Documental");
            exportData.Columns.Add("Tipo Radicado");
            exportData.Columns.Add("Usuario Asignado");

            Guid listName = new Guid(expedienteInfo.Rows[0][0].ToString());
            string listItemId = expedienteInfo.Rows[0]["ID"].ToString();
            SPList currentRadicadoList = SPContext.Current.Web.Lists[listName];
            SPFolder currentFolder = currentRadicadoList.GetItemById(int.Parse(listItemId)).Folder;
            IEnumerable<Radicado> radicadosExpediente = getRadicadosExpediente(currentFolder);
            var radicadosTomo = from Radicado item in radicadosExpediente
                                where item.NúmeroTomo == volumeId
                                select item;

            foreach (var item in radicadosTomo)
            {
                exportData.Rows.Add(
                    new object[] 
                    { 
                        item.NoRadicado, item.Created.ToString("dd/MM/yyyy hh:mm:ss"), item.RemitenteDestinatario, item.TipoDocumento, item.TipoRadicado, item.UsuarioAsignado
                    });
            }

            return exportData;
        }

        public DataTable GetRadicadosByExpedienteTable(string expedienteId)
        {
            if (expedienteId == string.Empty)
                throw new Exception("Debe ingresar el expediente");

            var expedienteInfo = getExpedienteInformation(expedienteId);
            if (expedienteInfo == null || expedienteInfo.Rows.Count == 0)
                throw new Exception("Expediente no encontrado");

            DataTable exportData = new DataTable();
            exportData.Columns.Add("Radicado");
            exportData.Columns.Add("Fecha Creacion");
            exportData.Columns.Add("Remitente / Destinatario");
            exportData.Columns.Add("Tipo Documental");
            exportData.Columns.Add("Tipo Radicado");
            exportData.Columns.Add("Usuario Asignado");

            Guid listName = new Guid(expedienteInfo.Rows[0][0].ToString());
            string listItemId = expedienteInfo.Rows[0]["ID"].ToString();
            SPList currentRadicadoList = SPContext.Current.Web.Lists[listName];
            SPFolder currentFolder = currentRadicadoList.GetItemById(int.Parse(listItemId)).Folder;
            IEnumerable<Radicado> radicadosExpediente = getRadicadosExpediente(currentFolder);

            foreach (var item in radicadosExpediente)
            {
                exportData.Rows.Add(
                    new object[] 
                    { 
                        item.NoRadicado, item.Created.ToString("dd/MM/yyyy hh:mm:ss"), item.RemitenteDestinatario, item.TipoDocumento, item.TipoRadicado, item.UsuarioAsignado
                    });
            }

            return exportData;
        }

        #region Private Methods

        private DataTable getExpedienteInformation(string expedienteId)
        {
            /////Este SPSiteDataQuery en vm-minhacienda simepre devolvia null.

            //List<string> viewFields = new List<string>() { "ID" };
            //List<string> viewListFields = new List<string>() { "Title" };
            //string camlQuery = string.Format("<Where><And><Eq><FieldRef Name='{0}' /><Value Type='Text'>{1}</Value></Eq><Eq><FieldRef Name='{2}' /><Value Type='Text'>{3}</Value></Eq></And></Where>", CustomSiteColumns.FIELD_DOCUMENT_EXPEDIENTE_ID, expedienteId, UserLibraryHelper.ContentTypeFieldName, GlobalConstants.CTTN_EXPEDIENTE);
            //SPSiteDataQuery query = QuerySiteHelper.getSiteQueryObject(GlobalConstants.GLOBAL_USER_LIBRARY_TEMPLATE, viewFields, viewListFields, camlQuery);
            //DataTable foundedItems = SPContext.Current.Web.GetSiteData(query);
            //return foundedItems;

            string camlQuery = string.Format("<Where><And><Eq><FieldRef Name='ContentType'/><Value Type='Computed'>Expediente</Value></Eq><Eq><FieldRef Name='Expediente_Id'/><Value Type='Text'>{0}</Value></Eq></And></Where>", expedienteId);

            SPSiteDataQuery q = new SPSiteDataQuery();
            q.ViewFields = "<FieldRef Name='ID' /><ListProperty Name='Title' /><FieldRef Name='ContentType' /><FieldRef Name='" + CustomSiteColumns.FIELD_DOCUMENT_EXPEDIENTE_ID + "' /><FieldRef Name='" + CustomSiteColumns.FIELD_DOCSET_UNIQUE_ID + "' />";
            q.Lists = string.Format("<Lists ServerTemplate='{0}' MaxListLimit='100' />", GlobalConstants.GLOBAL_USER_LIBRARY_TEMPLATE);
            q.Webs = "<Webs Scope='SiteCollection' />";
            q.Query = camlQuery;


            DataTable dt = null;
            using (SPSite currentSite = new SPSite(SPContext.Current.Web.Url))
            {
                using (SPWeb web = currentSite.OpenWeb())
                {
                    dt = web.GetSiteData(q);
                }
            }
            return dt;
        }

        private IEnumerable<Radicado> getRadicadosExpediente(SPFolder expedienteFolder)
        {
            SPQuery queryRecords = new SPQuery() { Query = "<OrderBy><FieldRef Name='Created' Ascending='True' /></OrderBy>" };
            List<Radicado> radicadosEncontrados = new List<Radicado>();
            queryRecords.Folder = expedienteFolder;
            SPListItemCollection radicados = expedienteFolder.Item.ParentList.GetItems(queryRecords);
            string expedienteOwner = expedienteFolder.Item[CustomSiteColumns.FIELD_EXPEDIENTE_ASSIGNED].ToString().GetUserWithOutDomain();
            foreach (SPListItem radicado in radicados)
                radicadosEncontrados.Add(this.getRadicadoListItem(radicado, expedienteOwner));

            return radicadosEncontrados;
        }

        private Radicado getRadicadoListItem(SPListItem listItem, string expedienteOwnerListName)
        {
            Radicado currentRadicado = new Radicado();

            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (SPSite site = new SPSite(SPContext.Current.Web.Url))
                {
                    using (SPWeb miWeb = site.OpenWeb())
                    {
                        currentRadicado.ParentExpedienteListName = listItem.ParentList.ID.ToString();
                        currentRadicado.ListId = miWeb.Lists.TryGetList(expedienteOwnerListName).ID;
                        if (listItem.ContentType.Name == GlobalConstants.CTTN_DOCUMENT_LINK)
                        {
                            SPList targetList = miWeb.Lists.TryGetList(listItem[CustomSiteColumns.FIELD_LINK_DOC_TARGET_LIST].ToString());
                            if (targetList != null)
                            {
                                try
                                {
                                    listItem = targetList.GetItemById(int.Parse(listItem[CustomSiteColumns.FIELD_LINK_DOC_TARGET_ID].ToString()));
                                    currentRadicado.ListId = listItem.ParentList.ID;
                                }
                                catch (Exception)
                                {
                                }
                            }
                        }
                        currentRadicado.NoRadicado = listItem[CustomSiteColumns.FIELD_DOCUMENT_RADICADO].ToString();
                        currentRadicado.Created = DateTime.Parse(listItem["Created"].ToString());
                        currentRadicado.RemitenteDestinatario = listItem[CustomSiteColumns.FIELD_DOCSET_SENDERRECEPT] == null ? string.Empty : listItem[CustomSiteColumns.FIELD_DOCSET_SENDERRECEPT].ToString();
                        currentRadicado.TipoDocumento = listItem[CustomSiteColumns.FIELD_DOCUMENT_DOCUMENTAL_TYPE] == null ? string.Empty : listItem[CustomSiteColumns.FIELD_DOCUMENT_DOCUMENTAL_TYPE].ToString();
                        currentRadicado.TipoRadicado = ((TaxonomyFieldValue)listItem[CustomSiteColumns.FIELD_DOCSET_KIND]).Label;

                        currentRadicado.Id = listItem.ID;
                        currentRadicado.UsuarioAsignado = listItem[CustomSiteColumns.FIELD_EXPEDIENTE_ASSIGNED] == null ? string.Empty : listItem[CustomSiteColumns.FIELD_EXPEDIENTE_ASSIGNED].ToString();
                        currentRadicado.Archivado = listItem[CustomSiteColumns.FIELD_DOCUMENT_FILED] == null ? new Nullable<Boolean>() : Boolean.Parse(listItem[CustomSiteColumns.FIELD_DOCUMENT_FILED].ToString());
                        currentRadicado.NúmeroTomo = listItem[CustomSiteColumns.FIELD_VOLUME_ID] == null ? string.Empty : listItem[CustomSiteColumns.FIELD_VOLUME_ID].ToString();
                        currentRadicado.RecibidoInterno = listItem[CustomSiteColumns.FIELD_DOCSET_INTERNAL_RECEPTION] == null ? false : Convert.ToBoolean(listItem[CustomSiteColumns.FIELD_DOCSET_INTERNAL_RECEPTION]);
                    }
                }
            });
            return currentRadicado;
        }

        #endregion
    }
}
